package com.fy.controller;

import com.fy.common.constants.Constants;
import com.fy.common.annotation.GlobalInterceptor;
import com.fy.mapper.FileInfoMapper;
import com.fy.pojo.dto.file.DownLoadCodeDTO;
import com.fy.pojo.dto.file.FileQueryDTO;
import com.fy.pojo.dto.file.RenameFileDTO;
import com.fy.pojo.dto.file.UploadFileDTO;
import com.fy.pojo.entity.FileInfo;
import com.fy.pojo.vo.file.FileStatisticsVO;
import com.fy.pojo.vo.file.FileTypeVO;
import com.fy.pojo.vo.file.FoloderVO;
import com.fy.pojo.vo.file.UploadResultVO;
import com.fy.pojo.vo.user.LoginUserVO;
import com.fy.service.FileInfoService;
import com.fy.utils.RedisUtils;
import com.fy.utils.StringTools;
import com.fy.utils.aliyunUtils.AliOssUtil;
import com.fy.utils.result.PageResult;
import com.fy.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@RestController("fileController")
@RequestMapping("/file")
public class FileController extends BaseController {

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 上传文字图片
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/ocrUpload")
    @GlobalInterceptor
    public Result<?> upload(MultipartFile file) throws Exception {
        log.info("开始文件上传：文件名：{}", file.getOriginalFilename());
        String url = aliOssUtil.uploadImg(file);
        log.info("文件上传完成，文件访问路径为：{}", url);
        return Result.success(url);
    }

    /**
     * 上传文件
     *
     * @param httpSession
     * @param uploadFileDTO
     * @return
     */
    @PostMapping("/uploadFile")
    @GlobalInterceptor
    public Result uploadFile(HttpSession httpSession, UploadFileDTO uploadFileDTO) throws IOException {
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        log.info("接受到的session信息:{}", loginUserVO);

        // 1. 检查 loginUserVO 是否为空
        if (loginUserVO == null) {
            return Result.error("用户未登录");
        }

        // 2. 检查 uploadFileDTO 是否为空
        if (uploadFileDTO == null || uploadFileDTO.getFile() == null) {
            return Result.error("上传文件不能为空");
        }

        String uploadId = fileInfoService.uploadFile(loginUserVO, uploadFileDTO);
        UploadResultVO uploadResultVO = new UploadResultVO();
        if (uploadId != null) {
            uploadResultVO.setStatus(Constants.UPLOADING);
            uploadResultVO.setFileId(uploadId);
        }

        if (Objects.equals(uploadId, null) && Objects.equals(uploadFileDTO.getChunkIndex(), "0")) {
            uploadResultVO.setStatus(Constants.UPLOAD_SECONDS);
            uploadResultVO.setFileId(null);
        }

        if (Objects.equals(uploadId, null) && !Objects.equals(uploadFileDTO.getChunkIndex(), "0")) {
            uploadResultVO.setStatus(Constants.UPLOAD_SUCCESS);
            uploadResultVO.setFileId(null);
        }

        log.info("上传文件返回结果:{}", uploadResultVO);
        return Result.success(uploadResultVO);
    }

    /**
     * 根据条件文件分页查询
     */
    @RequestMapping("/loadDataList")
    @GlobalInterceptor(checkParams = true)
    public Result<PageResult> loadDataList(HttpSession httpSession, FileQueryDTO queryDTO) {
        log.info("queryDTO:{}", queryDTO);
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        PageResult pageResult = fileInfoService.filePageQuery(queryDTO, loginUserVO);
        log.info("返回数据封装:{}", pageResult);
        return Result.success(pageResult);
    }

    /**
     * 查看文件
     *
     * @param response
     * @param fileId
     */
    @GetMapping("/getFile/{fileId}")
    @GlobalInterceptor
    public void getFile(HttpServletResponse response, @PathVariable String fileId) {
        FileInfo fileInfo = fileInfoService.getFilePath(fileId);
        readFile(response, fileInfo.getFilePath());
    }

    /**
     * 文件列表浏览视频
     *
     * @param fileId
     * @return
     */
    @GetMapping("/ts/getVideoInfo/{fileId}")
    @GlobalInterceptor
    public void getVideoInfo(HttpServletResponse response, @PathVariable String fileId) {
        log.info("getVideoInfo:{}", fileId);
        FileInfo fileInfo = fileInfoService.getFilePath(fileId);
        log.info("URL:{}", fileInfo.getFilePath());
        readFile(response, fileInfo.getFilePath());
    }

    /**
     * 删除文件
     *
     * @param fileIdList
     * @return
     */
    @PostMapping("/delFile")
    @GlobalInterceptor
    public Result delFile(@RequestParam("fileIds") List<String> fileIdList) {
        log.info("批量删除文件id接收:{}", fileIdList);
        fileInfoService.delFile(fileIdList);
        return Result.success();
    }

    /**
     * 重命名文件
     *
     * @param renameFileDTO
     * @return
     */
    @PostMapping("/rename")
    @GlobalInterceptor
    public Result rename(RenameFileDTO renameFileDTO) {
        fileInfoService.rename(renameFileDTO);
        return Result.success();
    }

    /**
     * 创建文件下载路径
     *
     * @param fileId
     * @return
     */
    @PostMapping("/createDownloadUrl/{code}")
    @GlobalInterceptor
    public Result createDownloadUrl(@PathVariable("code") String fileId) {
        return Result.success(fileInfoService.createDownloadURL(fileId));
    }

    /**
     * 获取文件下载路径
     *
     * @param request
     * @param response
     * @param redisDownLoadKey
     */
    @GetMapping("/download/{code}")
    @GlobalInterceptor
    public void download(HttpServletRequest request, HttpServletResponse response,
            @PathVariable("code") String redisDownLoadKey) throws Exception {
        DownLoadCodeDTO dto = (DownLoadCodeDTO) redisUtils.get(redisDownLoadKey);
        log.info("redis中的下载数据:{}", dto);
        if (null == dto) {
            return;
        }
        String filePath = dto.getFilePath();
        String fileName = dto.getFileName();
        response.setContentType("application/x-msdownload; charset=UTF-8");
        if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0) {// IE浏览器
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        readFile(response, filePath);
    }

    /**
     * 获取文件图标
     *
     * @param response
     * @param fileId
     * @param fileName
     */
    @GetMapping("/getImage/{imageFolder}/{imageName}")
    @GlobalInterceptor
    public void getImage(HttpServletResponse response, @PathVariable("imageFolder") String fileId,
            @PathVariable("imageName") String fileName) {
        log.info("fileId,fileName:{},{}", fileId, fileName);
        if (StringTools.isEmpty(fileId) || StringUtils.isBlank(fileId)) {
            return;
        }

        String imageSuffix = StringTools.getFileSuffix(fileName);
        String filePath = fileInfoMapper.selectById(fileId).getFileCover();
        imageSuffix = imageSuffix.replace(".", "");
        String contentType = "image/" + imageSuffix;
        response.setContentType(contentType);
        response.setHeader("Cache-Control", "max-age=2592000");
        readFile(response, filePath);
    }

    /**
     * 创建文件夹
     *
     * @param httpSession
     * @param filePid
     * @param fileName
     * @return
     */
    @PostMapping("/newFoloder")
    @GlobalInterceptor
    public Result newFoloder(HttpSession httpSession, String filePid, String fileName) {
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        FileInfo fileInfo = fileInfoService.newFoloder(filePid, fileName, loginUserVO);
        log.info("filePid,fileName:{},{}", filePid, fileName);
        return Result.success(fileInfo);
    }

    /**
     * 获取文件夹信息
     *
     * @param fileId
     * @return
     */
    @PostMapping("/getFolderInfo")
    @GlobalInterceptor
    public Result getFolderInfo(@RequestParam("path") String fileId) {
        log.info("fileId:{}", fileId);
        List<FoloderVO> foloderVO = fileInfoService.getFoloderInfo(fileId);
        return Result.success(foloderVO);
    }

    /**
     * 获取文件夹
     *
     * @param filePid
     * @param currentFileIds
     * @return
     */
    @PostMapping("/loadAllFolder")
    @GlobalInterceptor
    public Result loadAllFolder(HttpSession httpSession, String filePid, String currentFileIds) {
        log.info("filePid,currentFileIds:{},{}", filePid, currentFileIds);
        List<FileInfo> fileInfoList = fileInfoService
                .loadAllFolder((LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY), filePid, currentFileIds);
        return Result.success(fileInfoList);
    }

    /**
     * 移动文件
     *
     * @param fileIds
     * @param filePid
     * @return
     */
    @PostMapping("/changeFileFolder")
    @GlobalInterceptor
    public Result changeFileFolder(String fileIds, String filePid) {
        fileInfoService.changeFileFolder(fileIds, filePid);
        return Result.success();
    }

    /**
     * 获取文件统计信息
     *
     * @param session
     * @return
     */

    @PostMapping("/statistics")
    @GlobalInterceptor
    public Result<FileStatisticsVO> getFileStatistics(HttpSession session) {
        LoginUserVO loginUserVO = (LoginUserVO) session.getAttribute(Constants.SESSION_KEY);
        FileStatisticsVO statistics = fileInfoService.getFileStatistics(Math.toIntExact(loginUserVO.getId()));
        return Result.success(statistics);
    }

    @PostMapping("/typeDistribution")
    @GlobalInterceptor(checkLogin = true)
    public Result getFileTypeDistribution(HttpSession session) {
        FileTypeVO fileTypeVO = new FileTypeVO();
        List<FileTypeVO> distribution = new ArrayList<>();
        // 写一些图片，视频，文件等等相关的模拟数据
        fileTypeVO.setType("图片");
        fileTypeVO.setCount(60);
        fileTypeVO.setPercentage(0.44);
        distribution.add(fileTypeVO);
        FileTypeVO fileTypeVO1 = new FileTypeVO();
        fileTypeVO1.setType("视频");
        fileTypeVO1.setCount(160);
        fileTypeVO1.setPercentage(0.5);
        distribution.add(fileTypeVO1);
        FileTypeVO fileTypeVO2 = new FileTypeVO();
        fileTypeVO2.setType("文件");
        fileTypeVO2.setCount(16);
        fileTypeVO2.setPercentage(0.7);
        distribution.add(fileTypeVO2);
        // 再多加一些
        FileTypeVO fileTypeVO3 = new FileTypeVO();
        fileTypeVO3.setType("文档");
        fileTypeVO3.setCount(77);
        fileTypeVO3.setPercentage(0.9);
        distribution.add(fileTypeVO3);
        FileTypeVO fileTypeVO4 = new FileTypeVO();
        fileTypeVO4.setType("压缩包");
        fileTypeVO4.setCount(20);
        fileTypeVO4.setPercentage(0.2);
        distribution.add(fileTypeVO4);
        FileTypeVO fileTypeVO5 = new FileTypeVO();
        fileTypeVO5.setType("音乐");
        fileTypeVO5.setCount(16);
        fileTypeVO5.setPercentage(0.31);
        distribution.add(fileTypeVO5);
        FileTypeVO fileTypeVO6 = new FileTypeVO();
        fileTypeVO6.setType("其他");
        fileTypeVO6.setCount(19);
        fileTypeVO6.setPercentage(0.1);
        distribution.add(fileTypeVO6);
        return Result.success(distribution);
    }
}
